Vue 基础

基本介绍

官网文档:介绍 — Vue.js (vuejs.org)
全面教程:简介 | Vue.js (vuejs.org)
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

MVVM 思想

引入

在 MVVM 之前,开发人员从后端获取需要的数据模型,然后要通过 DOM 操作 Model 渲染到 View 中。而后当用户操作视图,我们还需要通过 DOM 获取 View 中的数据,然后同步到 Model 中。
例如在 Jsp 开发中我们用的各种 el 表达式,jstl 表达式就是例子,我需要手动动态的渲染数据,这就给我们带来了很大的麻烦。而且 DOM 操作十分的繁杂,就算有了 JQuery 这种第三库的帮助也不简单。

正式介绍

快速入门

其实这里讲到的 Vue 就是一个大型 js 库,所以根本不用什么其他的环境,只用引入 Vue.js 即可。

示例代码

<body>
<!--解读
1. div元素不是必须的,也可以是其它元素,比如span,但是约定都是将vue实例挂载到div
2. 因为div更加适合做布局
3. id 不是必须为app , 是程序员指定,一般我们就使用app
-->
<div id="app">
    <h1>欢迎你{{message}}-{{name}}</h1>
</div>
<!--引入vue.js-->
<script src="vue.js"></script>
<script>
    //创建Vue对象实例
    let vm = new Vue({
        el: "#app", //创建的vue实例挂载到 id=app的div
        data: { //data{} 表示数据池(model的有了数据), 有很多数据 ,以k-v形式设置(根据业务需要来设置)
            message: "Hello-Vue!",
            name: "你好"
        }
    })
</script>
</body>

解读:

注意事项

Vue 的绑定机制

数据绑定

单向渲染

我们通常在 html 中使用插值表达式 {{msg}} 来实现单向渲染非属性的内容,若数据池中存在 msg 属性,就会将 msg 替换成数据池中的数据。

由于无法用插值表达式渲染标签属性,于是就要借用 v-bind 指令来渲染。

利用 v-bind 指令来渲染标签的属性 attr。

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>单向数据渲染</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--解读
    1. 使用插值表达式引用 data数据池数据是在标签体内
    2. 如果是在标签/元素 的属性上去引用data数据池数据时,不能使用插值表达式
    3. 需要使用v-bind, 因为v-bind是vue来解析, 默认报红,但是不影响解析
    4. 如果不希望看到报红, 直接 alt+enter 引入 xmlns:v-bind
    -->
    <!--<img src="{{img_src}}">-->
    <img v-bind:src="img_src" v-bind:width="img_width">
    <img :src="img_src" :width="img_width">
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app", 
        data: { 
            message: "hello, 耗子精",
            img_src: "1.jpg",
            img_width: "200px"
        }
    })
</script>
</body>
</html>

再次强调:

双向绑定

v-model 可以完成双向数据绑定,即:

<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>双向数据渲染</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <input type="text" v-model="hobby.val"><br/><br/>
    <input type="text" :value="hobby.val"><br/><br/>
    <p>你输入的爱好是: {{hobby.val}}</p>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app", //创建的vue实例挂载到 id=app的div
        data: { //data{} 表示数据池(model的有了数据), 有很多数据 ,以k-v形式设置(根据业务需要来设置)
            message: "hi, 输入你的爱好",
            hobby: {
                val: "购物"
            }
        }
    })</script>
</body>
</html>

其他绑定

事件绑定

<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>事件处理</title>
</head>
<body>
<div id="app">
    <h1>{{message}}</h1>
    <!--解读
    1. v-on:click 表示我们要给button元素绑定一个click的事件
    2. sayHi() 表示绑定的方法, 在方法池 methods{} 定义的
    3. 底层仍然是dom处理
    4. 如果方法不需要传递参数,可以省略()
    5. v-on:click可以简写@, 但是需要浏览器支持
    -->
    <button v-on:click="sayHi()">点击输出</button>
    <button v-on:click="sayOk()">点击输出</button>
    <button v-on:click="sayHi">点击输出</button>
    <button @click="sayOk">点击输出</button>
</div>
<script src="vue.js"></script>
<script>
    let vm = new Vue({
        el: "#app",
        data: {
            message: "Vue事件处理的案例",
            name: "韩顺平教育"
        },
        //解读:
        // 1. 是一个methods属性, 对应的值是对象{}
        // 2. 在{} 中, 可以写很多的方法, 你可以这里理解是一个方法池
        // 3. 这里需要小伙伴有js的基础=>java web第4章
        methods: {
            sayHi() {
                console.log("hi, 银角大王~");
            },
            sayOk() {
                console.log("ok, 金角大王~");
            }
        }
    })
</script>
</body>
</html>

注意事项:

修饰符

修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()

<form v-on:submit.prevent="onSubmit">...</form>

具体实例,略,见事件处理 — Vue.js (vuejs.org)

条件渲染

类似于 jstl 表达式中的 <c:if>

<div v-if="Math.random() > 0.5">  
Now you see me  
</div>  
<div v-else>  
Now you don't  
</div> 
<!--                              -->
<div v-if="type === 'A'">  
A  
</div>  
<div v-else-if="type === 'B'">  
B  
</div>  
<div v-else-if="type === 'C'">  
C  
</div>  
<div v-else>  
Not A/B/C  
</div>

列表渲染

相当于 jstl 中的 <c:foreach>

<ul id="example-1">  
<li v-for="item in items" :key="item.message">  
{{ item.message }}  
</li>  
</ul>
var example1 = new Vue({
	el: '#example-1',  
	data: {    
		items: [      
			{ message: 'Foo' },
			{ message: 'Bar' }    
		]  
	}
})

解读:


<ul id="example-2">  
	<li v-for="(item, index) in items">  
		{{ parentMessage }} - {{ index }} - {{ item.message }}  
	</li>  
</ul>
var example2 = new Vue({  
	el: '#example-2',  
	data: {  
		parentMessage: 'Parent',  
		items: [  
			{ message: 'Foo' },  
			{ message: 'Bar' }  
		]  
	}  
})

用 v-for 来遍历一个对象的 property:

<ul id="v-for-object" class="demo">  
	<li v-for="value in object">  
		{{ value }}  
	</li>  
</ul>
new Vue({  
	el: '#v-for-object',  
	data: {  
		object: {  
			title: 'How to do lists in Vue',  
			author: 'Jane Doe',  
			publishedAt: '2016-04-10'  
		}  
	}  
})

你也可以提供第二个(或者更多也行)的参数为 property 名称 (也就是键名):

<div v-for="(value, name) in object">  
	{{ name }}: {{ value }}  
</div>

组件化编程

引入

正式介绍

全局组件

类似于 Java 的静态类,一旦注册了全局组件,就可以在所有的 Vue 实例中使用。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件化编程-全局组件</title>
</head>
<body>
<div id="app">
    <h1>组件化编程-全局组件</h1>
    <!--使用全局组件-->
    <counter></counter>
    <br/>
    <counter></counter>
    <counter></counter>
    <counter></counter>
    <counter></counter>
</div>

<div id="app2">
    <h1>组件化编程-全局组件-app2</h1>
    <!--使用全局组件-->
    <counter></counter>
    <counter></counter>
</div>
<script src="vue.js"></script>
<script>
    //1、定义一个全局组件, 名称为 counter
    //2. {} 表示就是我们的组件相关的内容
    //3. template 指定该组件的界面, 因为会引用到数据池的数据,所以需要是模板字符串
    Vue.component("counter", {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【全局组件化】</button>`,
        data() {//这里需要注意,和原来的方式不一样!!!!
            return {
                count: 10
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    })
    let vm = new Vue({
        el: "#app"
    })

    let vm2 =  new Vue({
        el: "#app2"
    })
</script>
</body>
</html>

局部组件

以通过一个普通的 JavaScript 对象来定义组件。把常用的组件放入到某个 js 文件中,类似于 Java 的工具包。

//定义一个组件, 组件的名称为 buttonCounter
    //扩展:
    //1. 可以把常用的组件,定义在某个commons.js中 export
    //2. 如果某个页面需要使用, 直接import
    const buttonCounter = {
        template: `<button v-on:click="click()">点击次数= {{count}} 次【局部组件化】</button>`,
        data() {//这里需要注意,和原来的方式不一样!!!!
            return {
                count: 10
            }
        },
        methods: {
            click() {
                this.count++;
            }
        }
    }
    //创建Vue实例,必须有
    let vm = new Vue({
        el: "#app",
        components: { //引入/注册某个组件, 此时my_counter就是一个组件, 是一个局部组件,他的使用范围在当前vue
            'my_counter': buttonCounter
        }
    })
    let vm2 = new Vue({
        el: "#app2",
        components :{//引入/注册组件buttonCounter
            'hsp_counter': buttonCounter
        }
    })
<div id="app">
    <h1>组件化编程-局部组件</h1>
    <!--使用局部组件 ,该组件是从挂载到app的vue中的-->
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
    <my_counter></my_counter><br/>
</div>

<div id="app2">
    <h1>组件化编程-局部组件-app2</h1>
    <!--使用局部组件 -->
    <hsp_counter></hsp_counter><br/>
    <hsp_counter></hsp_counter><br/>
</div>

总结

这是深入内容:
Vue-深入组件-插槽

更多关于组建的内容请查看官方文档:
组件基础 | Vue.js (vuejs.org)

生命周期和监听函数(钩子函数)

介绍